ユーザー認証

class LoginController < ApplicationController
  def index
  end

  def post
    user = User.find_by(username: params[:username])
    if user&.authenticate(params[:password])
        session[:username] = user.username
        redirect_to test_path , notice: "ログインしました"
    else
        flash.now[:notice] = "ユーザー名またはパスワードが正しくありません"
        render :index, status: :unprocessable_entity
    end
  end

  def delete
    session.delete(:username)
    redirect_to login_path, notice: "ログアウトしました"
  end
end
class TestController < ApplicationController
  before_action :authenticate_user

  def authenticate_user
    @current_user ||= User.find_by(username: session[:username]) if session[:username]
    redirect_to login_path, alert: "ログインが必要です" unless @current_user
  end

  def index
  end
end
Rails.application.routes.draw do
  get 'login', to: 'login#index'
  post 'login', to: 'login#post'
  delete 'login', to: vie'login#delete'

  get "test" => 'test#index'
end
上の例では、ログインしていない状態ではログインページにリダイレクトされるようにしている例です。

LoginControllerクラスのpostメソッドでは、userにUserモデルのusernameがビューから送信されてきたusernameのものを代入し、
if user&.authenticate(params[:password])

の部分でuserのデータの存在確認、ビューから送られてきたパスワードが正しいかの確認を行っています。
.authenticate(引数)は引数をハッシュ化し、モデルのpassword_digestフィールドと照合を行っています。

else時の
render :index, status: :unprocessable_entity

のstatus: :unprocessable_entityはHTTPステータスコード422(バリデーションエラーなどの理由でリソースの状態が正しくない)を返すという意味です。

deleteメソッドでは
session.delete(:username)

としてsession[:username]を削除することでログアウト状態にしています。

TestControllerクラスでは
before_action :authenticate_user

でメソッドの実行前にauthenticate_userメソッドを実行し、ログイン状態の確認を行うようにしています。

authenticate_userメソッドでは、
@current_user ||= User.find_by(username: session[:username]) if session[:username]

とし、
@current_user ||=

は@current_userが未定義、nil、false時にはその後ろの部分を代入するようにしています。
このようにすることでセッションのキャッシュを再利用することができます。
if session[:username]

はsession[:username]が定義済みでnil、false以外が代入されているときに
@current_user ||= User.find_by(username: session[:username])

を実行するという意味になります。


redirect_to login_path, alert: "ログインが必要です" unless current_user

unless @current_user

は@current_userが未定義、nil、false時にはその前の
redirect_to login_path, alert: "ログインが必要です"

を実行するという内容になっています。